home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Programming Languages Suite
/
ProgLangD.iso
/
BORLAND TURBO
/
CLASSINC.PAK
/
MEMMGR.H
< prev
next >
Wrap
C/C++ Source or Header
|
1997-05-05
|
14KB
|
493 lines
//----------------------------------------------------------------------------
// Borland BIDS Container Library
// Copyright (c) 1992, 1997 by Borland International, All Rights Reserved
//
//$Revision: 5.11 $
//
//----------------------------------------------------------------------------
#if !defined(CLASSLIB_MEMMGR_H)
#define CLASSLIB_MEMMGR_H
#if !defined(CLASSLIB_DEFS_H)
# include <classlib/defs.h>
#endif
#if !defined(CLASSLIB_STDTEMPL_H)
# include <classlib/stdtempl.h>
#endif
#if !defined(CLASSLIB_ALLOCTR_H)
# include <classlib/alloctr.h>
#endif
#if !defined(SERVICES_CHECKS_H)
# include <services/checks.h>
#endif
#if !defined(__STDLIB_H) && !defined(_INC_STDLIB)
# include <stdlib.h>
#endif
#if !defined(__DOS_H) && !defined(_INC_DOS)
# include <dos.h>
#endif
//#pragma option -Vo-
#if defined( BI_CLASSLIB_NO_po )
# pragma option -po-
#endif
#if defined(BI_NAMESPACE)
namespace ClassLib {
#endif
/*------------------------------------------------------------------------*/
/* */
/* template <class Alloc> class TMBlockList */
/* */
/* Used internally. */
/* */
/*------------------------------------------------------------------------*/
template <class Alloc> class TMBaseMemBlocks;
template <class Alloc> class TMBlockList
{
public:
TMBlockList( TMBlockList * );
private:
void *operator new( size_t, size_t, const Alloc& );
void operator delete( void * );
TMBlockList *Next;
friend TMBaseMemBlocks<Alloc>;
};
template <class Alloc>
inline TMBlockList<Alloc>::TMBlockList( TMBlockList<Alloc> *nxt ) :
Next( nxt )
{
}
template <class Alloc>
inline void *TMBlockList<Alloc>::operator new ( size_t sz,
size_t extra,
const Alloc& a )
{
return new(a)_TCHAR[sz+extra];
}
template <class Alloc>
inline void TMBlockList<Alloc>::operator delete ( void *ptr )
{
Alloc::operator delete [] (ptr);
}
#if defined( BI_OLDNAMES )
#define MBlockList TMBlockList
#endif
/*------------------------------------------------------------------------*/
/* */
/* class TBlockList */
/* */
/* Used internally. */
/* */
/*------------------------------------------------------------------------*/
class TBlockList : public TMBlockList<TStandardAllocator>
{
public:
TBlockList( TBlockList *blk ) :
TMBlockList<TStandardAllocator>( blk ) {}
};
#if defined( BI_OLDNAMES )
#define BlockList TBlockList
#endif
/*------------------------------------------------------------------------*/
/* */
/* template <class Alloc> class TMBaseMemBlocks */
/* */
/* Used internally. */
/* */
/*------------------------------------------------------------------------*/
template <class Alloc> class TMBaseMemBlocks :
public Alloc
{
public:
TMBaseMemBlocks( size_t = 8192 );
~TMBaseMemBlocks();
_TCHAR *Block() const { return REINTERPRET_CAST(_TCHAR *,CurBlock); }
unsigned Count() const { return BlockCount; }
int AllocBlock( size_t );
void FreeTo( unsigned );
size_t GetBlockSize() const { return BlockSize; }
private:
TMBlockList<Alloc> *CurBlock;
const size_t BlockSize;
unsigned BlockCount;
};
template <class Alloc>
inline TMBaseMemBlocks<Alloc>::TMBaseMemBlocks( size_t sz ) :
CurBlock(0),
BlockCount(0),
BlockSize(sz)
{
CHECK( sz != 0 );
}
template <class Alloc>
inline TMBaseMemBlocks<Alloc>::~TMBaseMemBlocks()
{
#if !defined( BI_WINDOWS_WEP_BUG )
FreeTo( 0 );
#endif
}
template <class Alloc> int TMBaseMemBlocks<Alloc>::AllocBlock( size_t sz )
{
TMBlockList<Alloc> *temp =
new( max(sz,BlockSize), *this ) TMBlockList<Alloc>( CurBlock );
CurBlock = temp+1;
BlockCount++;
return 1;
}
template <class Alloc> void TMBaseMemBlocks<Alloc>::FreeTo( unsigned term )
{
PRECONDITION( BlockCount >= term );
while( BlockCount > term )
{
TMBlockList<Alloc> *temp = CurBlock-1;
CurBlock = temp->Next;
delete[] temp;
BlockCount--;
}
}
#if defined( BI_OLDNAMES )
#define MBaseMemBlocks TMBaseMemBlocks
#endif
/*------------------------------------------------------------------------*/
/* */
/* class TBaseMemBlocks */
/* */
/* Used internally. */
/* */
/*------------------------------------------------------------------------*/
class TBaseMemBlocks : public TMBaseMemBlocks<TStandardAllocator>
{
public:
TBaseMemBlocks( size_t sz = 8192 ) :
TMBaseMemBlocks<TStandardAllocator>(sz) {}
};
#if defined( BI_OLDNAMES )
#define BaseMemBlocks TBaseMemBlocks
#endif
/*------------------------------------------------------------------------*/
/* */
/* template <class Alloc> class TMMemStack */
/* */
/* Managed memory stack. Implements mark and release style memory */
/* management, using the allocator Alloc. */
/* */
/*------------------------------------------------------------------------*/
template <class Alloc> class TMMarker;
template <class Alloc> class TMMemStack
{
public:
friend TMMarker<Alloc>;
TMMemStack( size_t = 8192 );
void *Allocate( size_t );
#if defined( BI_OLDNAMES )
void *allocate( size_t sz ) { return Allocate( sz ); }
#endif // BI_OLDNAMES
private:
TMBaseMemBlocks<Alloc> Data;
size_t CurLoc;
};
#if defined(BI_OLDNAMES)
# define MMemStack TMMemStack
#endif
template <class Alloc>
inline void *operator new( size_t sz, TMMemStack<Alloc>& m )
{
return m.Allocate( sz );
}
#if !defined(BI_NO_ARRAYNEW)
template <class Alloc>
inline void *operator new [] ( size_t sz, TMMemStack<Alloc>& m )
{
return m.Allocate( sz );
}
#endif
template <class Alloc> inline TMMemStack<Alloc>::TMMemStack( size_t sz ) :
Data( sz ),
CurLoc(sz)
{
CHECK( sz != 0 );
}
template <class Alloc> void *TMMemStack<Alloc>::Allocate( size_t sz )
{
sz = max( 1U, sz );
if( sz > Data.GetBlockSize() - CurLoc )
if( Data.AllocBlock( sz ) == 0 )
return 0;
else
CurLoc = 0;
void *temp = Data.Block() + CurLoc;
CurLoc += sz;
return temp;
}
/*------------------------------------------------------------------------*/
/* */
/* template <class Alloc> class TMMarker */
/* */
/* Provides the mark for TMMemStack. */
/* */
/*------------------------------------------------------------------------*/
template <class Alloc> class TMMarker
{
public:
TMMarker( TMMemStack<Alloc>& ms ) :
Memstk(ms),
Blk(ms.Data.Count()),
CurLoc(ms.CurLoc)
{
}
~TMMarker()
{
PRECONDITION( Blk < Memstk.Data.Count() ||
(Blk == Memstk.Data.Count() && CurLoc <= Memstk.CurLoc )
);
Memstk.Data.FreeTo( Blk );
Memstk.CurLoc = CurLoc;
}
private:
TMMemStack<Alloc>& Memstk;
const unsigned Blk;
const size_t CurLoc;
};
#if defined( BI_OLDNAMES )
#define MMarker TMMarker
#endif
/*------------------------------------------------------------------------*/
/* */
/* class TMemStack */
/* */
/* Implements mark and release style memory management using the */
/* standard allocator. */
/* */
/*------------------------------------------------------------------------*/
class TMemStack : public TMMemStack<TStandardAllocator>
{
public:
TMemStack( size_t sz = 8192 ) : TMMemStack<TStandardAllocator>(sz) {}
};
#if defined( BI_OLDNAMES )
#define MemStack TMemStack
#endif
/*------------------------------------------------------------------------*/
/* */
/* template <class Alloc> class TMarker */
/* */
/* Provides the mark for TMemStack. */
/* */
/*------------------------------------------------------------------------*/
class TMarker : public TMMarker<TStandardAllocator>
{
public:
TMarker( TMMemStack<TStandardAllocator>& ms ) :
TMMarker<TStandardAllocator>(ms) {}
};
/*------------------------------------------------------------------------*/
/* */
/* template <class Alloc> class TMMemBlocks */
/* */
/* Managed single-size block allocator. Allocates blocks */
/* of the size specified in the constructor, using the memory */
/* manager specified by Alloc. */
/* */
/*------------------------------------------------------------------------*/
template <class Alloc> class TMMemBlocks
{
public:
TMMemBlocks( size_t sz, unsigned count = 100 ) :
Mem( sz*count ),
FreeList(0),
Size( max(sz,sizeof(void *)) )
{
CHECK( sz != 0 && count != 0 );
}
void *Allocate( size_t sz)
{
PRECONDITION( Size == max(sz,sizeof(void *)) );
if( FreeList == 0 )
return Mem.Allocate( Size );
else
{
void *temp = FreeList;
FreeList = *(void **)temp;
return temp;
}
}
void Free( void * block)
{
*(void **)block = FreeList;
FreeList = block;
}
#if defined( BI_OLDNAMES )
void *allocate( size_t sz ) { return Allocate(sz); }
void free( void *ptr ) { Free(ptr); }
#endif // BI_OLDNAMES
private:
void *FreeList;
TMMemStack<Alloc> Mem;
size_t Size;
};
#if defined( BI_OLDNAMES )
#define MMemBlocks TMemBlocks
#endif
#if defined(FOO)
template <class Alloc>
inline TMMemBlocks<Alloc>::TMMemBlocks( size_t sz, unsigned count ) :
Mem( sz*count ),
FreeList(0),
Size( max(sz,sizeof(void *)) )
{
CHECK( sz != 0 && count != 0 );
}
#if (__DEBUG > 0)
template <class Alloc> inline void *TMMemBlocks<Alloc>::Allocate( size_t sz )
#else
template <class Alloc> inline void *TMMemBlocks<Alloc>::Allocate( size_t )
#endif
{
PRECONDITION( Size == max(sz,sizeof(void *)) );
if( FreeList == 0 )
return Mem.Allocate( Size );
else
{
void *temp = FreeList;
FreeList = *(void **)temp;
return temp;
}
}
template <class Alloc>
inline void TMMemBlocks<Alloc>::Free( void *block )
{
*(void **)block = FreeList;
FreeList = block;
}
#endif
/*------------------------------------------------------------------------*/
/* */
/* class TMemBlocks */
/* */
/* Single-size block allocator. Allocates blocks of the size */
/* specified in the constructor, using the global operator new */
/* and operator delete. */
/* */
/*------------------------------------------------------------------------*/
class TMemBlocks : public TMMemBlocks<TStandardAllocator>
{
public:
TMemBlocks( size_t sz, unsigned n = 100 ) :
TMMemBlocks<TStandardAllocator>( sz, n ) {}
};
#if defined(BI_OLDNAMES)
# define MemBlocks TMemBlocks
#endif
typedef TMMemBlocks<TStandardAllocator> TStandardBlocks;
#if defined(BI_PLAT_WIN16) && !defined(BI_DATA_NEAR)
typedef TMMemBlocks<TSharedAllocator> TSharedBlocks;
#endif
#if defined(BI_NAMESPACE)
} // namespace ClassLib
#endif
#if defined( BI_CLASSLIB_NO_po )
# pragma option -po.
#endif
//#pragma option -Vo.
#endif // CLASSLIB_MEMMGR_H